/*
 * Copyright (c) 2024 dragonSaberCaptain.All rights reserved.
 * 当前项目名:wisdom-parent
 * 当前模块名:common-tools
 * 当前文件的权限定名:com.wisdom.tools.system.SystemUtil
 * 当前文件的名称:SystemUtil.java
 * 当前文件的类名:SystemUtil
 * 上一次文件修改的日期时间:2024/1/19 下午1:31
 *
 */

package com.wisdom.tools.system;

import com.alibaba.fastjson2.JSON;
import com.wisdom.base.dto.SystemInfo;
import com.wisdom.tools.constant.Constant;
import com.wisdom.tools.file.FileUtil;
import com.wisdom.tools.string.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.SystemUtils;
import org.springframework.context.ApplicationContext;

import java.io.File;
import java.security.Provider;
import java.security.Security;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

@Slf4j
public class SystemUtil {
    private static SystemInfo systemInfo;

    public static void main(String[] args) {
        List<String> list = getPackageClassesName(null, SystemUtil.class, true, true);
        for (String name : list) {
            System.out.println(name);
        }
    }

    public static SystemInfo getSystemInfo() {
        if (systemInfo == null) {
            systemInfo = new SystemInfo();
        }
        return systemInfo;
    }

    /**
     * 获取某个包下的所有文件
     *
     * @param packagePath 包名全路径
     * @param addPath     是否返回 全路径
     * @param addClass    是否返回 .class结尾
     * @return java.util.List<java.lang.String>
     * @author captain
     * @datetime 2022-06-13 10:34:04
     */
    public static List<String> getPackageClassesName(String packagePath, Class<?> aClass, boolean addPath, boolean addClass) {
        List<String> filesPath = getFilesPath(packagePath, aClass);

        List<String> resultList = new ArrayList<>();

        int startIndex = 0;
        for (String className : filesPath) {
            if (addPath) {
                className = className.replace(File.separator, ".");
            } else {
                startIndex = className.lastIndexOf(File.separator) + 1;
            }

            if (addClass) {
                className = className.substring(startIndex);
            } else {
                className = className.substring(startIndex, className.lastIndexOf("."));
            }
            resultList.add(className);
        }
        return resultList;
    }

    /**
     * 已文件路径的形式,返回包下的所有类
     *
     * @param packagePath 包名全路径
     */
    public static List<String> getFilesPath(String packagePath, Class<?> aClass) {
        String filePath;
        if (StringUtil.isNotBlank(packagePath)) {
            filePath = Objects.requireNonNull(aClass.getResource(File.separator)).getPath() + packagePath.replace(".", File.separator);
        } else {
            filePath = Objects.requireNonNull(aClass.getResource("")).getPath();
        }

        List<File> fileList = FileUtil.getFilesByPath(filePath);

        List<String> resultFileList = new ArrayList<>();
        for (File file : fileList) {
            String subFilePath = file.getPath();
            subFilePath = subFilePath.substring(subFilePath.indexOf("classes") + 8);
            if (!subFilePath.contains("$")) { //排除内部类
                resultFileList.add(subFilePath);
            }
        }
        return resultFileList;
    }

    /**
     * 打印系统环境信息
     */
    public static SystemInfo printSystemInfo(Class<?> aClass) {
        SystemInfo systemInfo = getSystemInfo();
        systemInfo.setOsName(SystemUtils.OS_NAME);
        systemInfo.setOsArch(SystemUtils.OS_ARCH);
        systemInfo.setOsVersion(SystemUtils.OS_VERSION);
        systemInfo.setJavaVmSpecificationVersion(SystemUtils.JAVA_VM_SPECIFICATION_VERSION);
        systemInfo.setJavaVmSpecificationVendor(SystemUtils.JAVA_VM_SPECIFICATION_VENDOR);
        systemInfo.setJavaVmSpecificationName(SystemUtils.JAVA_VM_SPECIFICATION_NAME);
        systemInfo.setJavaVmVersion(SystemUtils.JAVA_VM_VERSION);
        systemInfo.setJavaVmName(SystemUtils.JAVA_VM_NAME);
        systemInfo.setJavaVmVendor(SystemUtils.JAVA_VM_VENDOR);
        systemInfo.setJavaVersion(SystemUtils.JAVA_VERSION);
        systemInfo.setProviders(printProviders());
        systemInfo.setName(aClass.getName());
        systemInfo.setSimpleName(aClass.getSimpleName());
        if (StringUtil.isNotBlank(aClass.getName())) {
            systemInfo.setServiceName(Constant.SPRING_APPLICATION_NAME);
            systemInfo.setPort(Constant.SERVER_PORT);
            systemInfo.setProfilesActive(Constant.SPRING_PROFILES_ACTIVES);
            systemInfo.setEnvironmentActive(Constant.SPRING_ENVIRONMENT_ACTIVES);
        }

        ProcessHandle current = ProcessHandle.current();
        if (current.info().user().isPresent()) {
            systemInfo.setUser(current.info().user().get());
        }
        if (current.info().arguments().isPresent()) {
            systemInfo.setArguments(current.info().arguments().get());
        }
        if (current.info().command().isPresent()) {
            systemInfo.setCommand(current.info().command().get());
        }
        if (current.info().commandLine().isPresent()) {
            systemInfo.setCommandLine(current.info().commandLine().get());
        }
        if (current.info().startInstant().isPresent()) {
            systemInfo.setStartInstant(current.info().startInstant().get());
        }
        if (current.info().totalCpuDuration().isPresent()) {
            systemInfo.setTotalCpuDuration(current.info().totalCpuDuration().get());
        }
        systemInfo.setPid(String.valueOf(ProcessHandle.current().pid()));
        log.info("系统信息(system info):{}", JSON.toJSONString(systemInfo));
        return systemInfo;
    }

    /**
     * 打印jre中算法提供者列表
     */
    public static String printProviders() {
        Provider[] providers = Security.getProviders();
        List<String> poviderName = Arrays.stream(providers).map(Provider::getName).toList();
        return StringUtil.join(poviderName, ",");
    }

    public static SystemInfo systemInit(ApplicationContext context, Class<?> aClass) {
        return printSystemInfo(aClass);
    }
}
